package com.example.holes;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.widget.ImageButton;

/*
 * GameThread is a thread separate from the view that is in charge
 * of the timing of invoking the engine to update/draw the game.
 * The most important part of the game thread is maintaining
 * UPS at the possible cost of FPS.
 */
public class GameThread extends Thread {
	private SurfaceHolder sh;
	private Handler handler;
	private Context context;
	private GameEngine gEngine;
	private Canvas canvas;
	
	private final static int MAX_UPS = Global.UPS; // desired ups
	private final static int WAIT_PERIOD = 1000 / Global.UPS; // ms between each update
	private final static int MAX_FRAME_SKIPS = 5;

	
	private boolean running = true;
	
	public GameThread(SurfaceHolder sh, Context context, Handler handler,
						GameEngine gEngine){
		this.sh = sh;
		this.handler = handler;
		this.context = context;
		this.gEngine = gEngine;
	}
	
	//This is the most important part of the code. It is invoked when the call to start() is
    //made from the SurfaceView class. It loops continuously until the game is finished or
    //the application is suspended.
    @Override
    public void run() {
    	long next_tick = System.currentTimeMillis();  // time when cycle began
    	int skippedFrames;	// # of frames being skipped
    	
    	while (running) {
			skippedFrames = 0;
			
			// ===UPDATE===
			// constant updating at Global.UPS
			// 
			while ( next_tick < System.currentTimeMillis() && skippedFrames < MAX_FRAME_SKIPS){
				gEngine.Update();
				
				next_tick += WAIT_PERIOD;
				skippedFrames++;
			}
			
			// ===DRAW===
			// draws as fast as possible--variable FPS
    		canvas = null;
    		try {
	    		canvas = sh.lockCanvas();
	    		synchronized (sh) {
	    			if (canvas != null){
	    				// clear
		    			canvas.drawColor(Color.BLACK);
		    			
		    			// draw
		    			gEngine.Draw(canvas);
	    			}
	    		} 
	    	}finally {
		    	// in case of exception the surface is not left in
		    	// an inconsistent state
	    		if (canvas != null) {
	    			sh.unlockCanvasAndPost(canvas);
	    		}
	    	}
	    	
	    	// end activity if the game has stopped
	    	if (gEngine.getStop())
	    		endGame();
	    }
    }
    
    // ends the game returning the player's score
    private void endGame(){
    	// save coins
    	SharedPreferences prefs = context.getSharedPreferences(
			      "com.example.holes", Context.MODE_PRIVATE);
    	prefs.edit().putInt("coins", GameState.coins).commit();
    	
    	// return score
	    Intent returnIntent = new Intent();
	    returnIntent.putExtra("score", gEngine.finalScore());
	    returnIntent.putExtra("completed", gEngine.completed());
	    ((Activity)context).setResult(Activity.RESULT_OK, returnIntent);
	    ((Activity)context).finish();
    }
    
    public void setRunning(boolean in){ this.running = in; }
    public boolean getRunning(){ return running; }
}
